﻿//  Copyright © 2009-2010 by Rhy A. Mednick
//  All rights reserved.
//  http://rhyduino.codeplex.com
//  
//  Redistribution and use in source and binary forms, with or without modification, 
//  are permitted provided that the following conditions are met:
//  
//  * Redistributions of source code must retain the above copyright notice, this list 
//    of conditions and the following disclaimer.
//  
//  * Redistributions in binary form must reproduce the above copyright notice, this 
//    list of conditions and the following disclaimer in the documentation and/or other 
//    materials provided with the distribution.
//  
//  * Neither the name of Rhy A. Mednick nor the names of its contributors may be used 
//    to endorse or promote products derived from this software without specific prior 
//    written permission.
//  
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
//  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
//  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
//  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
//  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
//  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
//  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
//  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
//  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Rhyduino.Test
{
    /// <summary>
    ///   Confirm that the enum values are what we expect them to be. Really, only a typo
    ///   could make them wrong, but it would be hell to track down that problem if
    ///   we didn't have these unit tests.
    /// </summary>
    [TestClass]
    public class EnumsTest
    {
        #region Public Methods

        /// <summary>
        ///   Confirm the values for the PinMode enum.
        /// </summary>
        [TestMethod]
        public void PinMode_Values()
        {
            var expected = new Dictionary<string, int>
                               {
                                   {"Input", 0},
                                   {"Output", 1},
                                   {"Analog", 2},
                                   {"Pwm", 3},
                                   {"Servo", 4},
                                   {"None", 0xFF}
                               };

            ValidateEnumValues(typeof (PinMode), expected);
        }

        /// <summary>
        ///   Confirm the values for the DigitalPinValue enum.
        /// </summary>
        [TestMethod]
        public void DigitalPinValue_Values()
        {
            var expected = new Dictionary<string, int>
                               {
                                   {"Low", 0x00},
                                   {"High", 0x01},
                                   {"None", 0xFF}
                               };

            ValidateEnumValues(typeof (DigitalPinValue), expected);
        }

        /// <summary>
        ///   Confirm the values for the RequestMessageType enum.
        /// </summary>
        [TestMethod]
        public void RequestMessageType_Values()
        {
            var expected = new Dictionary<string, int>
                               {
                                   {"ReportAnalogPin", 0xC0},
                                   {"ReportDigitalPort", 0xD0},
                                   {"SetPinMode", 0xF4},
                                   {"SystemReset", 0xFF},
                                   {"ProtocolVersion", 0x79},
                                   {"DigitalWrite", 0x90},
                                   {"AnalogWrite", 0xE0},
                                   {"SetSamplingInterval", 0x7A},
                                   {"None", 0x00},
                                   {"ServoConfig", 0x70}
                               };

            ValidateEnumValues(typeof (RequestMessageType), expected);
        }

        /// <summary>
        ///   Confirm the values for the ResponseMessageType enum.
        /// </summary>
        [TestMethod]
        public void ResponseMessageType_Values()
        {
            var expected = new Dictionary<string, int>
                               {
                                   {"SysexStart ", 0xF0},
                                   {"SysexEnd ", 0xF7},
                                   {"ProtocolVersion", 0x79},
                                   {"AnalogValue", 0xE0},
                                   {"DigitalValue", 0x90},
                                   {"None", 0x00}
                               };

            ValidateEnumValues(typeof (ResponseMessageType), expected);
        }

        #endregion

        #region Private Methods

        /// <summary>
        ///   Validates that the enumeration has the expected number of values, and that the 
        ///   values match what they're expected to be.
        /// </summary>
        /// <param name = "enumType">The enum type to test.</param>
        /// <param name = "expected">The dictionary containing the key/value pairs that we expect to see in the enum.</param>
        private static void ValidateEnumValues(Type enumType, Dictionary<string, int> expected)
        {
            // First verify that the enum has the correct number of elements.
            Assert.AreEqual(expected.Count, Enum.GetValues(enumType).Length);

            // Now check the values
            foreach (var key in expected.Keys)
            {
                var actual = (int) Enum.Parse(enumType, key);
                Assert.AreEqual(expected[key], actual);
            }
        }

        #endregion
    }
}